home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / tracker-4.13.lha / tracker / automaton.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-15  |  5.3 KB  |  225 lines

  1. /* automaton.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: automaton.c,v 4.8 1995/02/08 13:14:56 espie Exp $
  6.  * $Log: automaton.c,v $
  7.  * Revision 4.8  1995/02/08  13:14:56  espie
  8.  * *** empty log message ***
  9.  *
  10.  * Revision 4.8  1995/02/08  13:14:56  espie
  11.  * *** empty log message ***
  12.  *
  13.  * Revision 4.7  1995/02/01  20:41:45  espie
  14.  * *** empty log message ***
  15.  *
  16.  * Revision 4.7  1995/02/01  20:41:45  espie
  17.  * *** empty log message ***
  18.  *
  19.  * Revision 4.6  1995/02/01  16:39:04  espie
  20.  * Includes moved to defs.h
  21.  *
  22.  * Revision 4.6  1995/02/01  16:39:04  espie
  23.  * Includes moved to defs.h
  24.  *
  25.  *
  26.  * Revision 4.2  1994/08/23  18:19:46  espie
  27.  * Added speedmode option
  28.  * Abstracted IO calls.
  29.  * Use display_pattern.
  30.  * Fixed up repeat code, should work better now.
  31.  * Fixed bug with bad loops.
  32.  * Modified the way set_speed works.
  33.  * Corrected stupid bug (run_in_fg)
  34.  * Added bg/fg test.
  35.  * General cleanup
  36.  * Added finetune.
  37.  * Protracker commands.
  38.  *
  39.  * Revision 2.16  1992/11/17  17:15:37  espie
  40.  * New output for new interface
  41.  * Modified repeat logic: now works irregardless of repeat points.
  42.  * start
  43.  *
  44.  * Revision 2.8  1992/07/14  14:23:41  espie
  45.  * Changed fine speed command and comments.
  46.  * Added two level of fault tolerancy.
  47.  */
  48.      
  49.  
  50.      
  51. #include "defs.h"
  52. #include "song.h"
  53. #include "channel.h"
  54. #include "extern.h"
  55. #include "prefs.h"
  56.      
  57. ID("$Id: automaton.c,v 4.8 1995/02/08 13:14:56 espie Exp $")
  58.      
  59.  
  60. LOCAL void clear_repeats(a, from, upto)
  61. struct automaton *a;
  62. int from, upto;
  63.    {
  64.    int i;
  65.  
  66.    for (i = from; i <= upto; i++)
  67.       a->gonethrough[i] = FALSE;
  68.    }
  69.  
  70. LOCAL void reset_repeats(a)
  71. struct automaton *a;
  72.    {
  73.    clear_repeats(a, 0, a->info->length);
  74.    a->gonethrough[a->info->length] = TRUE;
  75.    }
  76.  
  77. /* updates the pattern to play in the automaton.
  78.  * Checks that the pattern actually exists.
  79.  * Checks for repetitions as well.
  80.  */
  81. LOCAL void set_pattern(a)
  82. struct automaton *a;
  83.    {
  84.    int p;
  85.  
  86.  
  87.    if (a->pattern_num >= a->info->length)
  88.       {
  89.       error = UNRECOVERABLE;
  90.       return;
  91.       }
  92.  
  93.    if (a->gonethrough[a->pattern_num])
  94.       {
  95.       error = ENDED;
  96.       reset_repeats(a);
  97.       }
  98.    else
  99.       a->gonethrough[a->pattern_num] = TRUE;
  100.  
  101.       /* there is a level of indirection in the format,
  102.        * i.e., patterns can be repeated.
  103.        */
  104.    p = a->info->patnumber[a->pattern_num];
  105.    if (p >= a->info->maxpat)
  106.       {
  107.       error = UNRECOVERABLE;
  108.       return;
  109.       }
  110.  
  111.    display_pattern(a->pattern_num, a->info->length, p);
  112.  
  113.    a->pattern = a->info->pblocks + p;
  114.    }
  115.  
  116. /* initialize all the fields of the automaton necessary
  117.  * to play a given song.
  118.  */
  119. void init_automaton(a, song, start)
  120. struct automaton *a;
  121. struct song *song;
  122. int start;
  123.    {
  124.    a->info = &song->info;
  125.    a->pattern_num = start;    /* first pattern */
  126.  
  127.    a->loop_note_num = 0;
  128.    a->loop_counter = 0;
  129.  
  130.    reset_repeats(a);
  131.  
  132.    a->note_num = 0;           /* first note in pattern */
  133.    a->counter = 0;            /* counter for the effect tempo */
  134.    a->speed = NORMAL_SPEED;   /* this is the default effect tempo */
  135.    a->finespeed = NORMAL_FINESPEED;    
  136.                               /* this is the fine speed (100%=NORMAL_FINESPEED) */
  137.    a->do_stuff = DO_NOTHING;   
  138.                               /* some effects affect the automaton,
  139.                                * we keep them here.
  140.                                */
  141.  
  142.    error = NONE;              /* Maybe we should not reset errors at
  143.                                * this point.
  144.                                */
  145.    set_pattern(a);
  146.    }
  147.  
  148. /* Gets to the next pattern, and displays stuff */
  149. LOCAL void advance_pattern(a)
  150. struct automaton *a;
  151.    {
  152.    if (++a->pattern_num >= a->info->length)
  153.       a->pattern_num = 0;
  154.    set_pattern(a);
  155.    a->note_num = 0;
  156.    }
  157.  
  158.         
  159.  
  160. /* process all the stuff which we need to advance in the song,
  161.  * including set_speed, set_skip, set_fastskip, and set_loop.
  162.  */
  163. void next_tick(a)
  164. struct automaton *a;
  165.    {
  166.       /* there are three classes of speed changes:
  167.        * 0 does nothing. (should stop)
  168.        * <32 is the effect speed (resets the fine speed).
  169.        * >=32 changes the finespeed, default 125
  170.        */
  171.     if (a->do_stuff & (SET_SPEED | SET_FINESPEED) == SET_SPEED | SET_FINESPEED)
  172.         switch(get_pref_scalar(PREF_SPEEDMODE))
  173.             {
  174.         case FINESPEED_ONLY:
  175.             a->do_stuff &= ~SET_SPEED;
  176.             break;
  177.         case SPEED_ONLY:
  178.             a->do_stuff &= ~SET_FINESPEED;
  179.         default:
  180.             break;
  181.             }
  182.         
  183.    if ((a->do_stuff & SET_SPEED) && (a->do_stuff & SET_FINESPEED))
  184.       {
  185.       a->speed = a->new_speed;
  186.       a->finespeed = a->new_finespeed; 
  187.       }
  188.    else if (a->do_stuff & SET_FINESPEED)
  189.       {
  190.       a->finespeed = a->new_finespeed;
  191.       }
  192.    else if (a->do_stuff & SET_SPEED)
  193.       {
  194.       a->speed = a->new_speed;
  195.       a->finespeed = NORMAL_FINESPEED;
  196.       }
  197.  
  198.    if (++a->counter >= a->speed)
  199.       {
  200.       a->counter = 0;
  201.          /* loop: may change note in pattern right away */
  202.       if ((a->do_stuff & JUMP_PATTERN) && --a->loop_counter > 0)
  203.          a->note_num = a->loop_note_num;
  204.       else if (a->do_stuff & SET_FASTSKIP)
  205.          {
  206.          a->pattern_num = a->new_pattern;
  207.          set_pattern(a);
  208.          a->note_num = 0;
  209.          }
  210.       else if (a->do_stuff & SET_SKIP)
  211.          {
  212.          advance_pattern(a);
  213.          a->note_num = a->new_note;
  214.          }
  215.       else
  216.          {
  217.          if (++a->note_num >= BLOCK_LENGTH)
  218.             advance_pattern(a);
  219.          }
  220.       a->do_stuff = DO_NOTHING;
  221.       }
  222.    }
  223.  
  224.  
  225.